package com.compty.security.manager;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.compty.core.hibernate.HibernateEntityDao;
import com.compty.core.page.Page;
import com.compty.security.cache.UserCache;
import com.compty.security.domain.Resc;
import com.compty.security.domain.Role;
import com.compty.security.domain.User;


/**
 * 用户管理Manager
 */
public class UserManager extends HibernateEntityDao<User>{
    /** * logger. */
    private static Logger logger = LoggerFactory.getLogger(UserManager.class);
    
    private static String prefix = "previlige_";
    
    /**
     * rescTypeMapp 映射资源类型对应的资源的一对多关系，以便快速查找.
     * 如method类型对应哪些资源实例，url资源类型对应哪些资源实例
     */
    private static Map<String, List<String>> rescTypeMapping;
    
    private UserCache userCache;
    private RoleManager roleManager;
    private RescManager rescManager;
    
    public void setUserCache(UserCache userCache) {
		this.userCache = userCache;
	}

	public void setRoleManager(RoleManager roleManager) {
		this.roleManager = roleManager;
	}

	public void setRescManager(RescManager rescManager) {
		this.rescManager = rescManager;
	}

	@SuppressWarnings("unchecked")
	public List<User> getAllUsers(){
    	String hql = "from User u where u.userState.id = ?";
    	return super.find(hql,1L);
    }

    /**
     * 删除用户时需在cache移除用户.
     *
     * @param o user
     */
    @Override
    public void remove(Object o) {
        super.remove(o);

        if (o instanceof User) {
            User user = (User) o;
            removeUserInCache(((User) o).getUsername());

            if (logger.isDebugEnabled()) {
                logger.debug("Deleted user " + user
                    + " including ACL permissions");
            }
        }
    }
    
    /**
     * 删除用户
     */
    public void removeById(Serializable id) {
    	
    	User user = get(id);
    	
    	remove(user);
    }

    /**
     * 保存User前需要检查当前用户名是否有更改，若有则需先在cache中去除再重新加入.
     *
     * @param o Object User type only.
     */
    @Override
    public void save(Object o) {
        User user = (User) o;
        boolean isNew = (user.getId() == null);
        String orginName = "";

        if (!isNew) {
            User orginUser = get(user.getId());
            orginName = orginUser.getUsername();
            getHibernateTemplate().evict(orginUser);
        }

        super.save(user);

        if (isNew) {
            saveUserInCache(user);
        } else {
            user = get(user.getId());
            removeUserInCache(orginName);
            saveUserInCache(user);
        }
    }

    private void saveUserInCache(User user) {

        if (user.getUsername() != null) {
        	
            Set<Role> roles = user.getRoles();
            List<String> list = new ArrayList<String>();
            for (Role role : roles) {
				Long id = role.getId();
				role = roleManager.get(id);
				
				Set<Resc> rescs = role.getRescs();
				for (Resc resc : rescs) {
					Long rId = resc.getId();
					resc = rescManager.get(rId);
					if(resc != null){
						list.add(resc.getResString());
					}
				}
			}
            String[] authorities = list.toArray(new String[list.size()]);
            userCache.put(prefix+user.getUsername(),authorities);
        }
    }

    /**
     * 根据用户名，从缓存中删除用户.
     *
     * @param username 用户名
     */
    public void removeUserInCache(String username) {
    	userCache.remove(username);
    	userCache.remove(prefix+username);
    }

	/**
	 *@Todo:列出正常用户列表
	 *@CreateTime:2011-11-7 上午09:30:47
	 * @param curPage 
	 * @param pageSize
	 */
	public Page findAvailableUser(Integer curPage, int pageSize) {
		
		String hql = "from User u where u.userState.id = ? and administratorFlag = ? order by u.id desc ";

		return super.pagedQuery(hql, curPage, pageSize,1L,"0");
	}
	
    public void initUserInCache(){
    	
    	userCache.clear();
    	
		List<User> users = getAllUsers();
		 
	    for (Iterator iter = users.iterator(); iter.hasNext();) {
	    	 User user = (User) iter.next();
	    	 saveUserInCache(user);
	    }
	    
	    // 获取所有的资源,以初始化 rescTypeMapping
        rescTypeMapping = new HashMap<String, List<String>>();

        List resclist = rescManager.getAllResource();

        for (Iterator iter = resclist.iterator(); iter.hasNext();) {
        	 Resc resc =  (Resc) iter.next();
            String resString = resc.getResString();
            List<String> typelist = rescTypeMapping.get(resc.getResType());

            if (typelist == null) {
                typelist = new ArrayList<String>();
                rescTypeMapping.put(resc.getResType(), typelist);
            }

            typelist.add(resString);
        }
    }
    
    public String[] getPreviligesByUser(String username){
    	
    	if(userCache.get(prefix+username) == null){
    		User user =  findUserByName(username);
    		saveUserInCache(user);
    	}
    	
    	String[] authorities = (String[]) userCache.get(prefix+username);
    	return authorities;
    }
    
    /**
    * @Description: 根据用户名查找User对象
    * @param @param username
     */
    public User findUserByName(String username){
    	return super.findUniqueBy("username", username);
    }
    
    
    /**
     * 根据资源类型,在rescTypeMapping职工获取所有该类型资源的对应的resource string.
     *
     * @param resType resource type
     * @return List
     */
    public List<String> getResourcesByType(String resType) {
        return rescTypeMapping.get(resType);
    }
   
}
